home *** CD-ROM | disk | FTP | other *** search
/ Software of the Month Club 2000 October / Software of the Month - Ultimate Collection Shareware 277.iso / pc / PROGRAMS / UTILITY / WINLINUX / DATA1.CAB / programs_-_include / ASM-MIPS / R4KCACHE.H < prev    next >
C/C++ Source or Header  |  1999-09-17  |  13KB  |  530 lines

  1. /*
  2.  * r4kcache.h: Inline assembly cache operations.
  3.  *
  4.  * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
  5.  *
  6.  * $Id: r4kcache.h,v 1.7 1997/12/18 13:00:45 ralf Exp $
  7.  *
  8.  * FIXME: Handle split L2 caches.
  9.  */
  10. #ifndef _MIPS_R4KCACHE_H
  11. #define _MIPS_R4KCACHE_H
  12.  
  13. #include <asm/asm.h>
  14. #include <asm/cacheops.h>
  15.  
  16. extern inline void flush_icache_line_indexed(unsigned long addr)
  17. {
  18.     __asm__ __volatile__(
  19.         ".set noreorder\n\t"
  20.         ".set mips3\n\t"
  21.         "cache %1, (%0)\n\t"
  22.         ".set mips0\n\t"
  23.         ".set reorder"
  24.         :
  25.         : "r" (addr),
  26.           "i" (Index_Invalidate_I));
  27. }
  28.  
  29. extern inline void flush_dcache_line_indexed(unsigned long addr)
  30. {
  31.     __asm__ __volatile__(
  32.         ".set noreorder\n\t"
  33.         ".set mips3\n\t"
  34.         "cache %1, (%0)\n\t"
  35.         ".set mips0\n\t"
  36.         ".set reorder"
  37.         :
  38.         : "r" (addr),
  39.           "i" (Index_Writeback_Inv_D));
  40. }
  41.  
  42. extern inline void flush_scache_line_indexed(unsigned long addr)
  43. {
  44.     __asm__ __volatile__(
  45.         ".set noreorder\n\t"
  46.         ".set mips3\n\t"
  47.         "cache %1, (%0)\n\t"
  48.         ".set mips0\n\t"
  49.         ".set reorder"
  50.         :
  51.         : "r" (addr),
  52.           "i" (Index_Writeback_Inv_SD));
  53. }
  54.  
  55. extern inline void flush_icache_line(unsigned long addr)
  56. {
  57.     __asm__ __volatile__(
  58.         ".set noreorder\n\t"
  59.         ".set mips3\n\t"
  60.         "cache %1, (%0)\n\t"
  61.         ".set mips0\n\t"
  62.         ".set reorder"
  63.         :
  64.         : "r" (addr),
  65.           "i" (Hit_Invalidate_I));
  66. }
  67.  
  68. extern inline void flush_dcache_line(unsigned long addr)
  69. {
  70.     __asm__ __volatile__(
  71.         ".set noreorder\n\t"
  72.         ".set mips3\n\t"
  73.         "cache %1, (%0)\n\t"
  74.         ".set mips0\n\t"
  75.         ".set reorder"
  76.         :
  77.         : "r" (addr),
  78.           "i" (Hit_Writeback_Inv_D));
  79. }
  80.  
  81. extern inline void invalidate_dcache_line(unsigned long addr)
  82. {
  83.     __asm__ __volatile__(
  84.         ".set noreorder\n\t"
  85.         ".set mips3\n\t"
  86.         "cache %1, (%0)\n\t"
  87.         ".set mips0\n\t"
  88.         ".set reorder"
  89.         :
  90.         : "r" (addr),
  91.           "i" (Hit_Invalidate_D));
  92. }
  93.  
  94. extern inline void invalidate_scache_line(unsigned long addr)
  95. {
  96.     __asm__ __volatile__(
  97.         ".set noreorder\n\t"
  98.         ".set mips3\n\t"
  99.         "cache %1, (%0)\n\t"
  100.         ".set mips0\n\t"
  101.         ".set reorder"
  102.         :
  103.         : "r" (addr),
  104.           "i" (Hit_Invalidate_SD));
  105. }
  106.  
  107. extern inline void flush_scache_line(unsigned long addr)
  108. {
  109.     __asm__ __volatile__(
  110.         ".set noreorder\n\t"
  111.         ".set mips3\n\t"
  112.         "cache %1, (%0)\n\t"
  113.         ".set mips0\n\t"
  114.         ".set reorder"
  115.         :
  116.         : "r" (addr),
  117.           "i" (Hit_Writeback_Inv_SD));
  118. }
  119.  
  120. /*
  121.  * The next two are for badland addresses like signal trampolines.
  122.  */
  123. extern inline void protected_flush_icache_line(unsigned long addr)
  124. {
  125.     __asm__ __volatile__(
  126.         ".set noreorder\n\t"
  127.         ".set mips3\n"
  128.         "1:\tcache %1,(%0)\n"
  129.         "2:\t.set mips0\n\t"
  130.         ".set reorder\n\t"
  131.         ".section\t__ex_table,\"a\"\n\t"
  132.         STR(PTR)"\t1b,2b\n\t"
  133.         ".previous"
  134.         :
  135.         : "r" (addr),
  136.           "i" (Hit_Invalidate_I));
  137. }
  138.  
  139. extern inline void protected_writeback_dcache_line(unsigned long addr)
  140. {
  141.     __asm__ __volatile__(
  142.         ".set noreorder\n\t"
  143.         ".set mips3\n"
  144.         "1:\tcache %1,(%0)\n"
  145.         "2:\t.set mips0\n\t"
  146.         ".set reorder\n\t"
  147.         ".section\t__ex_table,\"a\"\n\t"
  148.         STR(PTR)"\t1b,2b\n\t"
  149.         ".previous"
  150.         :
  151.         : "r" (addr),
  152.           "i" (Hit_Writeback_D));
  153. }
  154.  
  155. #define cache16_unroll32(base,op)                \
  156.     __asm__ __volatile__("                    \
  157.         .set noreorder;                    \
  158.         .set mips3;                    \
  159.         cache %1, 0x000(%0); cache %1, 0x010(%0);    \
  160.         cache %1, 0x020(%0); cache %1, 0x030(%0);    \
  161.         cache %1, 0x040(%0); cache %1, 0x050(%0);    \
  162.         cache %1, 0x060(%0); cache %1, 0x070(%0);    \
  163.         cache %1, 0x080(%0); cache %1, 0x090(%0);    \
  164.         cache %1, 0x0a0(%0); cache %1, 0x0b0(%0);    \
  165.         cache %1, 0x0c0(%0); cache %1, 0x0d0(%0);    \
  166.         cache %1, 0x0e0(%0); cache %1, 0x0f0(%0);    \
  167.         cache %1, 0x100(%0); cache %1, 0x110(%0);    \
  168.         cache %1, 0x120(%0); cache %1, 0x130(%0);    \
  169.         cache %1, 0x140(%0); cache %1, 0x150(%0);    \
  170.         cache %1, 0x160(%0); cache %1, 0x170(%0);    \
  171.         cache %1, 0x180(%0); cache %1, 0x190(%0);    \
  172.         cache %1, 0x1a0(%0); cache %1, 0x1b0(%0);    \
  173.         cache %1, 0x1c0(%0); cache %1, 0x1d0(%0);    \
  174.         cache %1, 0x1e0(%0); cache %1, 0x1f0(%0);    \
  175.         .set mips0;                    \
  176.         .set reorder"                    \
  177.         :                        \
  178.         : "r" (base),                    \
  179.           "i" (op));
  180.  
  181. extern inline void blast_dcache16(void)
  182. {
  183.     unsigned long start = KSEG0;
  184.     unsigned long end = (start + dcache_size);
  185.  
  186.     while(start < end) {
  187.         cache16_unroll32(start,Index_Writeback_Inv_D);
  188.         start += 0x200;
  189.     }
  190. }
  191.  
  192. extern inline void blast_dcache16_page(unsigned long page)
  193. {
  194.     unsigned long start = page;
  195.     unsigned long end = (start + PAGE_SIZE);
  196.  
  197.     while(start < end) {
  198.         cache16_unroll32(start,Hit_Writeback_Inv_D);
  199.         start += 0x200;
  200.     }
  201. }
  202.  
  203. extern inline void blast_dcache16_page_indexed(unsigned long page)
  204. {
  205.     unsigned long start = page;
  206.     unsigned long end = (start + PAGE_SIZE);
  207.  
  208.     while(start < end) {
  209.         cache16_unroll32(start,Index_Writeback_Inv_D);
  210.         start += 0x200;
  211.     }
  212. }
  213.  
  214. extern inline void blast_icache16(void)
  215. {
  216.     unsigned long start = KSEG0;
  217.     unsigned long end = (start + icache_size);
  218.  
  219.     while(start < end) {
  220.         cache16_unroll32(start,Index_Invalidate_I);
  221.         start += 0x200;
  222.     }
  223. }
  224.  
  225. extern inline void blast_icache16_page(unsigned long page)
  226. {
  227.     unsigned long start = page;
  228.     unsigned long end = (start + PAGE_SIZE);
  229.  
  230.     while(start < end) {
  231.         cache16_unroll32(start,Hit_Invalidate_I);
  232.         start += 0x200;
  233.     }
  234. }
  235.  
  236. extern inline void blast_icache16_page_indexed(unsigned long page)
  237. {
  238.     unsigned long start = page;
  239.     unsigned long end = (start + PAGE_SIZE);
  240.  
  241.     while(start < end) {
  242.         cache16_unroll32(start,Index_Invalidate_I);
  243.         start += 0x200;
  244.     }
  245. }
  246.  
  247. extern inline void blast_scache16(void)
  248. {
  249.     unsigned long start = KSEG0;
  250.     unsigned long end = KSEG0 + scache_size;
  251.  
  252.     while(start < end) {
  253.         cache16_unroll32(start,Index_Writeback_Inv_SD);
  254.         start += 0x200;
  255.     }
  256. }
  257.  
  258. extern inline void blast_scache16_page(unsigned long page)
  259. {
  260.     unsigned long start = page;
  261.     unsigned long end = page + PAGE_SIZE;
  262.  
  263.     while(start < end) {
  264.         cache16_unroll32(start,Hit_Writeback_Inv_SD);
  265.         start += 0x200;
  266.     }
  267. }
  268.  
  269. extern inline void blast_scache16_page_indexed(unsigned long page)
  270. {
  271.     unsigned long start = page;
  272.     unsigned long end = page + PAGE_SIZE;
  273.  
  274.     while(start < end) {
  275.         cache16_unroll32(start,Index_Writeback_Inv_SD);
  276.         start += 0x200;
  277.     }
  278. }
  279.  
  280. #define cache32_unroll32(base,op)                \
  281.     __asm__ __volatile__("                    \
  282.         .set noreorder;                    \
  283.         .set mips3;                    \
  284.         cache %1, 0x000(%0); cache %1, 0x020(%0);    \
  285.         cache %1, 0x040(%0); cache %1, 0x060(%0);    \
  286.         cache %1, 0x080(%0); cache %1, 0x0a0(%0);    \
  287.         cache %1, 0x0c0(%0); cache %1, 0x0e0(%0);    \
  288.         cache %1, 0x100(%0); cache %1, 0x120(%0);    \
  289.         cache %1, 0x140(%0); cache %1, 0x160(%0);    \
  290.         cache %1, 0x180(%0); cache %1, 0x1a0(%0);    \
  291.         cache %1, 0x1c0(%0); cache %1, 0x1e0(%0);    \
  292.         cache %1, 0x200(%0); cache %1, 0x220(%0);    \
  293.         cache %1, 0x240(%0); cache %1, 0x260(%0);    \
  294.         cache %1, 0x280(%0); cache %1, 0x2a0(%0);    \
  295.         cache %1, 0x2c0(%0); cache %1, 0x2e0(%0);    \
  296.         cache %1, 0x300(%0); cache %1, 0x320(%0);    \
  297.         cache %1, 0x340(%0); cache %1, 0x360(%0);    \
  298.         cache %1, 0x380(%0); cache %1, 0x3a0(%0);    \
  299.         cache %1, 0x3c0(%0); cache %1, 0x3e0(%0);    \
  300.         .set mips0;                    \
  301.         .set reorder"                    \
  302.         :                        \
  303.         : "r" (base),                    \
  304.           "i" (op));
  305.  
  306. extern inline void blast_dcache32(void)
  307. {
  308.     unsigned long start = KSEG0;
  309.     unsigned long end = (start + dcache_size);
  310.  
  311.     while(start < end) {
  312.         cache32_unroll32(start,Index_Writeback_Inv_D);
  313.         start += 0x400;
  314.     }
  315. }
  316.  
  317. /*
  318.  * Call this function only with interrupts disabled or R4600 V2.0 may blow
  319.  * up on you.
  320.  *
  321.  * R4600 v2.0 bug: "The CACHE instructions Hit_Writeback_Inv_D,
  322.  * Hit_Writeback_D, Hit_Invalidate_D and Create_Dirty_Excl_D will only
  323.  * operate correctly if the internal data cache refill buffer is empty.  These
  324.  * CACHE instructions should be separated from any potential data cache miss
  325.  * by a load instruction to an uncached address to empty the response buffer."
  326.  * (Revision 2.0 device errata from IDT available on http://www.idt.com/
  327.  * in .pdf format.)
  328.  */
  329. extern inline void blast_dcache32_page(unsigned long page)
  330. {
  331.     unsigned long start = page;
  332.     unsigned long end = (start + PAGE_SIZE);
  333.  
  334.     /*
  335.      * Sigh ... workaround for R4600 v1.7 bug.  Explanation see above.
  336.      */
  337.     *(volatile unsigned long *)KSEG1;
  338.  
  339.     __asm__ __volatile__("nop;nop;nop;nop");
  340.     while(start < end) {
  341.         cache32_unroll32(start,Hit_Writeback_Inv_D);
  342.         start += 0x400;
  343.     }
  344. }
  345.  
  346. extern inline void blast_dcache32_page_indexed(unsigned long page)
  347. {
  348.     unsigned long start = page;
  349.     unsigned long end = (start + PAGE_SIZE);
  350.  
  351.     while(start < end) {
  352.         cache32_unroll32(start,Index_Writeback_Inv_D);
  353.         start += 0x400;
  354.     }
  355. }
  356.  
  357. extern inline void blast_icache32(void)
  358. {
  359.     unsigned long start = KSEG0;
  360.     unsigned long end = (start + icache_size);
  361.  
  362.     while(start < end) {
  363.         cache32_unroll32(start,Index_Invalidate_I);
  364.         start += 0x400;
  365.     }
  366. }
  367.  
  368. extern inline void blast_icache32_page(unsigned long page)
  369. {
  370.     unsigned long start = page;
  371.     unsigned long end = (start + PAGE_SIZE);
  372.  
  373.     while(start < end) {
  374.         cache32_unroll32(start,Hit_Invalidate_I);
  375.         start += 0x400;
  376.     }
  377. }
  378.  
  379. extern inline void blast_icache32_page_indexed(unsigned long page)
  380. {
  381.     unsigned long start = page;
  382.     unsigned long end = (start + PAGE_SIZE);
  383.  
  384.     while(start < end) {
  385.         cache32_unroll32(start,Index_Invalidate_I);
  386.         start += 0x400;
  387.     }
  388. }
  389.  
  390. extern inline void blast_scache32(void)
  391. {
  392.     unsigned long start = KSEG0;
  393.     unsigned long end = KSEG0 + scache_size;
  394.  
  395.     while(start < end) {
  396.         cache32_unroll32(start,Index_Writeback_Inv_SD);
  397.         start += 0x400;
  398.     }
  399. }
  400.  
  401. extern inline void blast_scache32_page(unsigned long page)
  402. {
  403.     unsigned long start = page;
  404.     unsigned long end = page + PAGE_SIZE;
  405.  
  406.     while(start < end) {
  407.         cache32_unroll32(start,Hit_Writeback_Inv_SD);
  408.         start += 0x400;
  409.     }
  410. }
  411.  
  412. extern inline void blast_scache32_page_indexed(unsigned long page)
  413. {
  414.     unsigned long start = page;
  415.     unsigned long end = page + PAGE_SIZE;
  416.  
  417.     while(start < end) {
  418.         cache32_unroll32(start,Index_Writeback_Inv_SD);
  419.         start += 0x400;
  420.     }
  421. }
  422.  
  423. #define cache64_unroll32(base,op)                \
  424.     __asm__ __volatile__("                    \
  425.         .set noreorder;                    \
  426.         .set mips3;                    \
  427.         cache %1, 0x000(%0); cache %1, 0x040(%0);    \
  428.         cache %1, 0x080(%0); cache %1, 0x0c0(%0);    \
  429.         cache %1, 0x100(%0); cache %1, 0x140(%0);    \
  430.         cache %1, 0x180(%0); cache %1, 0x1c0(%0);    \
  431.         cache %1, 0x200(%0); cache %1, 0x240(%0);    \
  432.         cache %1, 0x280(%0); cache %1, 0x2c0(%0);    \
  433.         cache %1, 0x300(%0); cache %1, 0x340(%0);    \
  434.         cache %1, 0x380(%0); cache %1, 0x3c0(%0);    \
  435.         cache %1, 0x400(%0); cache %1, 0x440(%0);    \
  436.         cache %1, 0x480(%0); cache %1, 0x4c0(%0);    \
  437.         cache %1, 0x500(%0); cache %1, 0x540(%0);    \
  438.         cache %1, 0x580(%0); cache %1, 0x5c0(%0);    \
  439.         cache %1, 0x600(%0); cache %1, 0x640(%0);    \
  440.         cache %1, 0x680(%0); cache %1, 0x6c0(%0);    \
  441.         cache %1, 0x700(%0); cache %1, 0x740(%0);    \
  442.         cache %1, 0x780(%0); cache %1, 0x7c0(%0);    \
  443.         .set mips0;                    \
  444.         .set reorder"                    \
  445.         :                        \
  446.         : "r" (base),                    \
  447.           "i" (op));
  448.  
  449. extern inline void blast_scache64(void)
  450. {
  451.     unsigned long start = KSEG0;
  452.     unsigned long end = KSEG0 + scache_size;
  453.  
  454.     while(start < end) {
  455.         cache64_unroll32(start,Index_Writeback_Inv_SD);
  456.         start += 0x800;
  457.     }
  458. }
  459.  
  460. extern inline void blast_scache64_page(unsigned long page)
  461. {
  462.     unsigned long start = page;
  463.     unsigned long end = page + PAGE_SIZE;
  464.  
  465.     while(start < end) {
  466.         cache64_unroll32(start,Hit_Writeback_Inv_SD);
  467.         start += 0x800;
  468.     }
  469. }
  470.  
  471. extern inline void blast_scache64_page_indexed(unsigned long page)
  472. {
  473.     unsigned long start = page;
  474.     unsigned long end = page + PAGE_SIZE;
  475.  
  476.     while(start < end) {
  477.         cache64_unroll32(start,Index_Writeback_Inv_SD);
  478.         start += 0x800;
  479.     }
  480. }
  481.  
  482. #define cache128_unroll32(base,op)                \
  483.     __asm__ __volatile__("                    \
  484.         .set noreorder;                    \
  485.         .set mips3;                    \
  486.         cache %1, 0x000(%0); cache %1, 0x080(%0);    \
  487.         cache %1, 0x100(%0); cache %1, 0x180(%0);    \
  488.         cache %1, 0x200(%0); cache %1, 0x280(%0);    \
  489.         cache %1, 0x300(%0); cache %1, 0x380(%0);    \
  490.         cache %1, 0x400(%0); cache %1, 0x480(%0);    \
  491.         cache %1, 0x500(%0); cache %1, 0x580(%0);    \
  492.         cache %1, 0x600(%0); cache %1, 0x680(%0);    \
  493.         cache %1, 0x700(%0); cache %1, 0x780(%0);    \
  494.         cache %1, 0x800(%0); cache %1, 0x880(%0);    \
  495.         cache %1, 0x900(%0); cache %1, 0x980(%0);    \
  496.         cache %1, 0xa00(%0); cache %1, 0xa80(%0);    \
  497.         cache %1, 0xb00(%0); cache %1, 0xb80(%0);    \
  498.         cache %1, 0xc00(%0); cache %1, 0xc80(%0);    \
  499.         cache %1, 0xd00(%0); cache %1, 0xd80(%0);    \
  500.         cache %1, 0xe00(%0); cache %1, 0xe80(%0);    \
  501.         cache %1, 0xf00(%0); cache %1, 0xf80(%0);    \
  502.         .set mips0;                    \
  503.         .set reorder"                    \
  504.         :                        \
  505.         : "r" (base),                    \
  506.           "i" (op));
  507.  
  508. extern inline void blast_scache128(void)
  509. {
  510.     unsigned long start = KSEG0;
  511.     unsigned long end = KSEG0 + scache_size;
  512.  
  513.     while(start < end) {
  514.         cache128_unroll32(start,Index_Writeback_Inv_SD);
  515.         start += 0x1000;
  516.     }
  517. }
  518.  
  519. extern inline void blast_scache128_page(unsigned long page)
  520. {
  521.     cache128_unroll32(page,Hit_Writeback_Inv_SD);
  522. }
  523.  
  524. extern inline void blast_scache128_page_indexed(unsigned long page)
  525. {
  526.     cache128_unroll32(page,Index_Writeback_Inv_SD);
  527. }
  528.  
  529. #endif /* !(_MIPS_R4KCACHE_H) */
  530.